#pragma once
#include "queue.h"
#include "raw_json_message.h"

const String FINISH_SIG = "FINISH";

using buffer = raw_json_message_buffer;

static buffer recv_buffer, send_buffer;

extern void handler() {
	//Receive data
	for (;;) {
		auto tmp_data = raw_json_message(Serial.readStringUntil(char("\n")));
		if (tmp_data.compareTo(FINISH_SIG) == 0)break;
		recv_buffer.push(tmp_data);
	}
	//Send data
	for (;; send_buffer.len() > 0) {
		Serial.println(send_buffer.pop());
	}
	//Send FINISH signal
	Serial.println(FINISH_SIG);
}

class serial_bus {
public:
	serial_bus(int rate = 115200, uint8_t pin = 2) {
		baud_rate = rate;
		interrupt_pin = pin;
	}
	~serial_bus() {
		stop();
	}

	raw_json_message recv() {
		while (recv_buffer.len() == 0);
		return recv_buffer.pop();
	}

	void send(raw_json_message data) {
		return send_buffer.push(data);
	}

	void run() {
		Serial.begin(baud_rate);
		pinMode(interrupt_pin, INPUT);
		attachInterrupt(digitalPinToInterrupt(interrupt_pin), handler, LOW);
	}

	void stop() {
		Serial.end();
		detachInterrupt(digitalPinToInterrupt(interrupt_pin));
	}

	bool is_running() {
		return true;
	}

	size_t recv_data_available() {
		return recv_buffer.len();
	}
private:
	uint8_t interrupt_pin;
	int baud_rate;
};
